
#include "FontsetNotebook.h"
#include "StringUtil.h"
#include "FontsetPanelExt.h"
#include "ProjectSettingsDlg.h"
#include <wx/filename.h>

#include <tinyxml/tinyxml.h>

FontsetNotebook::FontsetNotebook(void)
    : wxAuiNotebook()
{
    mViewGridlines = true;
    mViewWidths = true;
}

FontsetNotebook::FontsetNotebook( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
    : wxAuiNotebook( parent, id, pos, size, style )
{
    //Reset();
    mViewGridlines = true;
    mViewWidths = true;
}

FontsetNotebook::~FontsetNotebook(void)
{
}

//Create
bool FontsetNotebook::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    bool success = wxAuiNotebook::Create( parent, id, pos, size, style );
    //if ( success )
    //    Reset();
    return success;
}

//AddPage
bool FontsetNotebook::AddPage( wxWindow* page, const wxString& caption, bool select, const wxBitmap& bitmap )
{
    bool success = wxAuiNotebook::AddPage( page, caption, select, bitmap );
    if ( success )
        Modify( true );
    return success;
}

//AddFontset
bool FontsetNotebook::AddFontset()
{
    StringUtil::String name = "Fontset";
    if ( GetPageCount() )
    {
        std::stringstream stream;
        stream << GetPageCount();
        name += stream.str();
    }
    return AddFontset( name );
}

//AddFontset
bool FontsetNotebook::AddFontset( const wxString& name )
{
    FontsetPanelExt* page = new FontsetPanelExt( name, this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
    bool success = AddPage( page, name, true );
    return success;
}


//Clear
void FontsetNotebook::Clear()
{
    if ( GetPageCount() == 0 )
        return;

    // Remove all existing pages:
    while ( GetPageCount() )
    {
        DeletePage( 0 );
    }
    Modify( true );
}

//Reset
void FontsetNotebook::Reset()
{
    Clear();
    EditProjectInformation();

    // Add an initial fontset page
    AddFontset();
    Modify( false );
}

//EditProjectInformation
void FontsetNotebook::EditProjectInformation()
{
    // Ask the user for project information
    ProjectSettingsDlg settingsDlg( this );
    settingsDlg.SetAuthor( mAuthor );
    settingsDlg.SetNotes( mNotes );
    settingsDlg.SetCopyright( mCopyright );
    if ( settingsDlg.ShowModal() == wxID_OK )
    {
        mAuthor     = settingsDlg.GetAuthor();
        mNotes      = settingsDlg.GetNotes();
        mCopyright  = settingsDlg.GetCopyright();
    }
}

bool FontsetNotebook::IsModified() const
{
    // If the notebook is flagged as modified (i.e. a tab added or removed) then
    // we can just return that flag.  Otherwise, we should dig a bit deeper, and
    // check each page.
    if ( !mIsModified )
    {
        for ( size_t curPage = 0; curPage < GetPageCount(); curPage++ )
        {
            FontsetPanelExt* page = wxDynamicCast( GetPage( curPage ), FontsetPanelExt );
            if ( page && page->IsModified() )
                return true;
        }
    }
    return mIsModified;
}

void FontsetNotebook::Modify( bool mod )
{
    mIsModified = mod;

    // If the modified flag is set to 'false', set the flag for all pages:
    if ( !mIsModified )
    {
        for ( size_t curPage = 0; curPage < GetPageCount(); curPage++ )
        {
            FontsetPanelExt* page = wxDynamicCast( GetPage( curPage ), FontsetPanelExt );
            if ( page )
                page->Modify( false );
        }
    }
}

bool FontsetNotebook::SaveFile( const wxString& filename )
{
    // Get the file name:
    wxFileName fileUtil( filename );
    wxString projectName = fileUtil.GetName();
    wxString pathLocation = fileUtil.GetPath() + wxFileName::GetPathSeparator();

    TiXmlDocument doc;  
    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  
    doc.LinkEndChild( decl ); 
 
    TiXmlElement* root = new TiXmlElement( "project" );  
    doc.LinkEndChild( root );

    TiXmlElement* node = new TiXmlElement( "name" );
    root->LinkEndChild( node );
    TiXmlText* text = new TiXmlText( projectName.ToAscii() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "author" );
    root->LinkEndChild( node );
    text = new TiXmlText( mAuthor.c_str() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "notes" );
    root->LinkEndChild( node );
    text = new TiXmlText( mNotes.c_str() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "copyright" );
    root->LinkEndChild( node );
    text = new TiXmlText( mCopyright.c_str() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "date" );
    root->LinkEndChild( node );
    text = new TiXmlText( wxDateTime::Now().Format( "%B %d, %Y  %I:%M:%S %p" ).c_str() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "creator" );
    root->LinkEndChild( node );
    text = new TiXmlText( "Hieroglyphics" );
    node->LinkEndChild( text );

    node = new TiXmlElement( "fontsetCount" );
    root->LinkEndChild( node );

    size_t fontsetCount = GetPageCount();
    StringUtil::String fontsetCountStr = StringUtil::ToString( fontsetCount );
    text = new TiXmlText( fontsetCountStr.c_str() );
    node->LinkEndChild( text );

    node = new TiXmlElement( "fontSetList" );
    root->LinkEndChild( node );

    // Write the fontsets:
    for ( int curSet = 0; curSet < fontsetCount; curSet++ )
    {
        // Get the current page:
        FontsetPanelExt* page = static_cast< FontsetPanelExt* >( GetPage( curSet ) );
        if ( page )
        {
            TiXmlElement* fontsetNode = new TiXmlElement( "fontset" );
            node->LinkEndChild( fontsetNode );

            // Write the fontset index:
            TiXmlElement* indexNode = new TiXmlElement( "index" );
            fontsetNode->LinkEndChild( indexNode );
            text = new TiXmlText( StringUtil::ToString( curSet ).c_str() );
            indexNode->LinkEndChild( text );

            //page->SavePNG( fontsetNode, pathLocation.ToAscii() );
            page->SavePNG( fontsetNode, StringUtil::String( pathLocation.ToAscii() ) );
        }
    }

    doc.SaveFile( filename.ToAscii() );  

    return true;
}

bool FontsetNotebook::LoadFile( const wxString& filename )
{
    // Get the file name:
    wxFileName fileUtil( filename );
    wxString projectName = fileUtil.GetName();
    wxString pathLocation = fileUtil.GetPath() + wxFileName::GetPathSeparator();

    TiXmlDocument doc( filename.ToAscii() );
    if ( doc.LoadFile() )
    {
        // Remove all existing pages:
        Clear();

        TiXmlNode* projNode = doc.FirstChild( "project" );
        TiXmlHandle projHandle( projNode );

        // Read the project settings

        // Go over the fontsets and load them
        TiXmlElement* fontsetNode = projHandle.FirstChild( "fontSetList" ).FirstChild( "fontset" ).Element();
        for ( fontsetNode; fontsetNode; fontsetNode = fontsetNode->NextSiblingElement( "fontset" ) )
        {
            // Read the name of the fontset
            TiXmlHandle fontsetHandle( fontsetNode );
            //TiXmlNode* nameNode = fontsetNode->FirstChild( "name" );
            TiXmlNode* nameNode = fontsetHandle.FirstChild( "identifier" ).FirstChild().Node();
            if ( nameNode )
            {
                // Read the fontset name and create the page
                StringUtil::String name = nameNode->Value();
                FontsetPanelExt* page = new FontsetPanelExt( name.c_str(), this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );

                // Read the fontset
                page->LoadPage( fontsetNode );

                // Add the fontset to the notebook
                bool success = AddPage( page, name, true );
            }
        }
    }

    return true;
}

//SetViewGridlines
void FontsetNotebook::SetViewGridlines( bool flag )
{
    mViewGridlines = flag;

    FontsetPanelExt* page = wxDynamicCast( GetPage( GetSelection() ), FontsetPanelExt );
    if ( page )
    {
        page->Refresh();
        page->Update();
    }
}

//GetViewGridlines
bool FontsetNotebook::GetViewGridlines() const
{
    return mViewGridlines;
}

//SetViewWidths
void FontsetNotebook::SetViewWidths( bool flag )
{
    mViewWidths = flag;

    FontsetPanelExt* page = wxDynamicCast( GetPage( GetSelection() ), FontsetPanelExt );
    if ( page )
    {
        page->Refresh();
        page->Update();
    }
}

//GetViewWidths
bool FontsetNotebook::GetViewWidths() const
{
    return mViewWidths;
}
